class Swiper {
    constructor (container, options) {
        this._options = {
            swiper: '.mshop-swiper',
            item: '.mshop-swiper-item',
            header: '.mshop-swiper-header',
            headerItem: '.mshop-swiper-header-item',
            headerSelector: '.mshop-swiper-header-selector',
            threshold: 50,
            broadcast: false,
            display_header: false,
            blur_header: '',
            blur_scroll: '',
            blur_index: 0
        }

        for (let key in options) {
            this._options[key] = options[key];
        }

        this.$container = container;
        this.$box = this.$container.querySelector(this._options.swiper);
        this.$items = this.$container.querySelectorAll(this._options.item);

        this.current = 0;
        this.scroll_blur = 0;
        this.direction = '';
        this._offset = 0;
        this._width = this.$container.offsetWidth;
        this.count = this.$items.length;

        this._start = {};
        this._move = {};
        this._end = {};

        this._init();
        this._bind_touch();
    }

    swiper_to (index) {
        this.current = index;
        this._show();
    }

    _init () {
        this._updateRects();
        this._updateHeader();
        setTimeout(this._setHeaderBlurByScroll.bind(this), 0)
    }

    _bind_touch () {
        const check_vux_swiper = (target) => {
            return Boolean(target
                        && target.parentNode
                        && target.parentNode.parentNode
                        && target.parentNode.parentNode.classList.contains('vux-swiper-item'));
        }

        const touchstartHandler = (e) => {
            if (check_vux_swiper(e.target)) {
                return false;
            }

            this._start.x = e.changedTouches[0].pageX;
            this._start.y = e.changedTouches[0].pageY;

            this.$box.style.transition = 'none';
            if (this._display_header()) {
                this.$headerSelector.style.transition = 'none';
            }
        }

        const touchmoveHandler = (e) => {
            if (check_vux_swiper(e.target)) {
                return false;
            }

            this._move.x = e.changedTouches[0].pageX;
            this._move.y = e.changedTouches[0].pageY;

            const x_distance = this._move.x - this._start.x;
            const y_distance = this._move.y - this._start.y;

            if (this.direction != 'y' && Math.abs(x_distance) > Math.abs(y_distance)) {
                this.direction = 'x';

                // 禁止滑动最边缘的操作（可以考虑加个禁止滑动的动画设计）
                if ((this.current === 0 && x_distance > 0) || (this.current === this.count - 1 && x_distance < 0)) {
                    return false;
                }

                this.$box.style.transform = `translate3d(${x_distance - this._offset}px, 0, 0)`;

                this._scrollHeaderSelector(x_distance / this._width);
                this._setHeaderBlur(x_distance / this._width);
                e.preventDefault();
            } else {
                this.direction = 'y';
            }
        }

        const touchendHandler = (e) => {
            if (check_vux_swiper(e.target)) {
                return false;
            }

            this.direction = '';

            this._end.x = e.changedTouches[0].pageX;
            this._end.y = e.changedTouches[0].pageY;

            const x_distance = this._end.x - this._start.x;
            const y_distance = this._end.y - this._start.y;

            this._start = {}
            this._move = {}
            this._end = {}

            if (Math.abs(x_distance) > Math.abs(y_distance)) {
                if (Math.abs(x_distance) > this._options.threshold) {
                    if (x_distance > 0) {
                        this.current = (this.current > 0)? this.current - 1: 0;
                    } else {
                        this.current = (this.current < this.count - 1)? this.current + 1: this.count - 1
                    }
                }

                this._show();
            }
        }

        const transitionEndHandler = (e) => {
            if (e.target !== this.$box) {
                return false;
            }

            e.preventDefault();
        }

        this.$container.addEventListener('touchstart', touchstartHandler, false);
        this.$container.addEventListener('touchmove', touchmoveHandler, false);
        this.$container.addEventListener('touchend', touchendHandler, false);
        this.$box.addEventListener('transitionend', transitionEndHandler, false);
    }


    _show () {
        this._offset = this.current * this._width;

        this.$box.style.transform = `translate3d(${-this._offset}px, 0, 0)`;
        this.$box.style.transition = '300ms'

        if (this._options.broadcast) {
            this._options.broadcast(this.current);
        }

        this._setHeaderSelector();
        this._setHeaderBlur();
    }

    _setHeaderBlur (percent=0) {
        if (this._blur_header()) {
            const next_index = percent > 0? this.current - 1 : this.current + 1;
            if (this.current != this._options.blur_index && next_index != this._options.blur_index) {
                return this._blur_opacity(1);
            }

            this._blur_opacity(Math.abs(percent > 0? 1 - percent : -percent));
        }
    }

    _blur_header() {
        return Boolean(this._options.blur_header);
    }

    _blur_opacity (value) {
        if (this.scroll_blur <= value) {
            this.$header.style.backgroundColor = `rgba(244, 67, 54, ${value})`;
        }
    }

    _setHeaderBlurByScroll(repeat=false) {
        if (this._blur_header()) {
            this.$headerBlur = this.$container.querySelector(this._options.blur_header);
            this.$scrollBlur = this.$container.querySelector(this._options.blur_scroll);

            if (!this.$headerBlur || !this.$scrollBlur) {
                if (!repeat) {
                    // 第一次可能用于子组件没有被渲染进dom里面去，所以300ms重复运行一次
                    setTimeout(() => {
                        this._setHeaderBlurByScroll(true);
                        if (!this.$headerBlur || !this.$scrollBlur) {
                            this._options.blur_header = '';
                            return;
                        }
                    }, 300);
                }

                return;
            }

            const _scroll_header = () => {
                if (this.$scrollBlur.scrollTop > this.$headerBlur.offsetHeight) {
                    this._blur_opacity(0);
                } else {
                    const scroll_blur = this.$scrollBlur.scrollTop / this.$headerBlur.offsetHeight;
                    this.scroll_blur = scroll_blur;
                    this._blur_opacity(scroll_blur);
                }
            }

            this.$scrollBlur.addEventListener('scroll', _scroll_header);
            _scroll_header();
        }
    }

    _updateHeaderBlur() {

    }

    _setHeaderSelector() {
        if (!this._display_header()) {
            return
        }

        const index = this.current;
        if (index < 0 || index >= this.$headerItems.length) {
            return
        }

        const item = this.$headerItems[index];
        this.$headerSelector.style.transition = '300ms';
        this.$headerSelector.style.width = `${item.offsetWidth}px`
        this.$headerSelector.style.transform = `translate(${item.offsetLeft}px, 0)`;
    }

    _scrollHeaderSelector(percent=0) {
        if (!this._display_header()) {
            return
        }

        const index = this.current;
        if (index < 0 || index >= this.$headerItems.length) {
            return;
        }

        const item = this.$headerItems[index];
        const index_offset = (() => {
            const next = index + (percent > 0? -1 : 1);
            if (next < 0) return index;
            else if (next >= this.$headerItems.length) return index;

            return next;
        })();

        const next_item = this.$headerItems[index_offset];

        this.$headerSelector.style.width = `${item.offsetWidth +
            (next_item.offsetWidth - item.offsetWidth) * Math.abs(percent)}px`;

        this.$headerSelector.style.transform = `translate(${item.offsetLeft +
            (next_item.offsetLeft - item.offsetLeft) * Math.abs(percent)}px, 0)`;
    }


    _display_header() {
        return this._options.display_header;
    }

    _updateHeader() {
        if (this._display_header()) {
            this.$header = this.$container.querySelector(this._options.header);
            this.$headerItems = this.$container.querySelectorAll(this._options.headerItem);
            this.$headerSelector = this.$container.querySelector(this._options.headerSelector);


            for (let i = 0; i < this.$headerItems.length; i++) {
                this.$headerItems[i].addEventListener('click', () => {
                    this.current = i;
                    this._show();
                }, false);
            }

            this._setHeaderSelector();
        }
    }

    _updateRects () {
        this.$box.style.width = this._width * this.count + 'px';

        Array.prototype.forEach.call(this.$items, ($item) => {
            $item.style.width = this._width + 'px'
        })
    }
}

export default Swiper
